package spring.cloud.tasks.tasks_manager.task_item_assign.pick_up.executor.task;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import spring.cloud.tasks.common.curator.Curator;
import spring.cloud.tasks.common.task_item_allot.Executor;
import spring.cloud.tasks.common.task_item_allot.TaskItem;
import spring.cloud.tasks.tasks_manager.task_item_assign.PreferExecutorSettings;
import spring.cloud.tasks.tasks_manager.task_item_assign.TaskItemAssignUtils;
import spring.cloud.tasks.tasks_manager.task_item_assign.pick_up.PickUp;

import java.util.ArrayList;
import java.util.List;

/**
 * 任务的executor上线，executor或者该任务级别平衡摘取，只摘取该任务的shard；添加的新的shard；
 */
@Slf4j
@Setter
@Getter
public class PickUpWhenTaskExecutorOnline extends PickUp {
    private String taskId;
    private String executorId;


    @Override
    protected void log() {
        log.info("Execute the {}, taskId is {}, executorName is {}", this.getClass().getSimpleName(), taskId, executorId);
    }

    @Override
    public boolean pickUp(Curator curator,//
                          List<String> taskIdList,//
                          List<String> enableTaskIdList,//
                          List<TaskItem> pickUpEdTaskItemList,//
                          List<TaskItem> discardTaskItemList,//
                          List<Executor> onlineExecutorList,//
                          List<Executor> ownTrafficOnlineExecutorList,//
                          PreferExecutorSettings preferExecutorSettings
    ) throws Exception {
        // 很小的可能性：status的新增事件先于ip的新增事件
        // 那么，如果lastOnlineExecutorList不包含executorName，则添加一个新的Executor
        // 添加当前任务至taskIdList
        Executor targetOnlineExecutor = null;
        for (int i = 0; i < onlineExecutorList.size(); i++) {
            Executor onlineExecutor = onlineExecutorList.get(i);
            if (onlineExecutor.getExecutorId().equals(executorId)) {
                targetOnlineExecutor = onlineExecutor;
                break;
            }
        }
        if (targetOnlineExecutor == null) {
            targetOnlineExecutor = new Executor();
            targetOnlineExecutor.setExecutorId(executorId);

            targetOnlineExecutor.setIp(TaskItemAssignUtils.getIp(curator, executorId));//可能返回为空 代表Executor已经挂掉了 但是能够走到这代表该执行器刚刚上线 理论上不会为空
            targetOnlineExecutor.setNotFlowControl(TaskItemAssignUtils.executorIsNotFlowControl(curator, executorId));
            targetOnlineExecutor.setTaskIdList(new ArrayList<String>());
            targetOnlineExecutor.setTaskItemList(new ArrayList<TaskItem>());
            targetOnlineExecutor.setTotalLoadLevel(0);
            onlineExecutorList.add(targetOnlineExecutor);
            if (targetOnlineExecutor.isNotFlowControl()) {
                ownTrafficOnlineExecutorList.add(targetOnlineExecutor);
            }
        }
        if (!targetOnlineExecutor.getTaskIdList().contains(taskId)) {
            targetOnlineExecutor.getTaskIdList().add(taskId);
        }

        // 如果该Executor流量被摘取，则无需摘取，返回true
        if (!targetOnlineExecutor.isNotFlowControl()) {
            return true;
        }

        pickUp(curator, enableTaskIdList, pickUpEdTaskItemList, ownTrafficOnlineExecutorList, preferExecutorSettings);

        return true;
    }

    //如果一个任务配置了优先list,那么需要把没有在优先配置列表的先移除,
    //如果没有配置则不管
    public void pickUp(Curator curator, //
                       List<String> enableTaskIdList, //
                       List<TaskItem> pickUpEdTaskItemList, //
                       List<Executor> onlineOwnTrafficExecutorList,//
                       PreferExecutorSettings preferExecutorSettings) throws Exception {
        boolean preferExecutorIdListIsConfigured = preferExecutorSettings.taskIdToIsConfiguredPreferExecutorIdListMap.get(taskId); // 是否配置了preferList
        List<String> preferExecutorIdListConfigured = preferExecutorSettings.taskIdToConfiguredPreferExecutorIdListMap.get(taskId); // 配置态的preferList
        if (preferExecutorIdListIsConfigured) {
            if (preferExecutorIdListConfigured.contains(executorId)) {
                //尝试平衡摘取
                TaskItemAssignUtils.balancePickUp(TaskItemAssignUtils.getOnlineExecutorListInPreferOrDisPreferExecutorIdListConfigured(taskId, preferExecutorIdListConfigured, onlineOwnTrafficExecutorList), taskId, pickUpEdTaskItemList);
            } else {
                return;//可以不用处理了
            }
        } else {
            // 如果有分片正在运行，则平衡摘取
            TaskItemAssignUtils.balancePickUp(TaskItemAssignUtils.getSupportedTaskIdOwnTrafficOnlineExecutorList(onlineOwnTrafficExecutorList, taskId), taskId, pickUpEdTaskItemList);
        }


    }


}
